/** @mainpage BOBBLE FRUIT
  * Boobble Fruit è un gioco single player, in cui il giocatore deve muovere un draghetto 
  * a destra e a sinistra e cercare di sparare ai robot che scendono, e mangiare la frutta e i dolci. 
  * Per ogni robot ucciso vengono aggiunti dei punti al punteggio totale, per ogni robot non ucciso invece 
  * viene tolta una vita, senza più possibilità di recuperarla. 
  * La frutta aumenta il punteggio se presa con la testa del drago, se gli si spara invece va a sottrarre 
  * un tot di punti, se il punteggio diventa negativo il gioco finisce. 
  *
  * NON è un gioco in cui si arriva a un traguardo e si vince, bensì più alto è il punteggio 
  * e meglio è.
  * La velocità dei robot aumenta ogni 2000 punti, fino ai 10'000 punti a cui si ferma.
  *
  *Il progetto è diviso in quattro moduli: 
  *  1 MODULO 
  * main e funzione cambia_stato, inoltre sono dichiarate le variabili globali, 
  * che sono poi incluse negli altri file tramite l'header globali.h , dove sono definite extern.
  *  2 MODULO
  * inizializzazioni.cc, sono presenti tutte le funzioni per la crezione degli oggetti del gioco, quali ::Bolle, ::Drago, ::Robot, ::Frutta
  *  3 MODULO
  * disegna.cc comprende tutte le funzioni dedite al disegno degli oggetti sulla finestra di gioco, vengono richiamate nei momenti opportuni,
  * esempio disegna_drago viene chiamato solo in ::FASE_GIOCO e ::FASE_PAUSA, in più ci sono anche le funzioni di update, perchè logicamente 
  * correlate al disegno.
  *  4 MODULO
  * collsioni.cc comprende tutte le funzioni che gestiscono le collisioni tra gli oggetti. Per gestire le collisioni vengono richiamate le
  * due funzioni principali, collisioni_X e collisioni_Y
  *
  * Questo programma è stato sviluppato usando le funzioni di libreria di Allegro 5.
  *
  * Include due livelli di debug/tracing e alcune asserzioni per rendere il programma più robusto. Le asserzioni che necessitano della
  * libreria <cassert> sono state eliminate.
  *
  * Durante il gioco c'è la possibilità di mettere in pausa.
  *
  * @author Martina Casari
  *
  */
#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_native_dialog.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <iostream>
#include <sstream>
#include "models.h"
#include "globali.h"
#include "inizializzazioni.h"
#include "collisioni.h"
#include "disegno.h"
#include "debug.h"

using namespace std;


#ifdef DEBUG_MODE
/**Maschera per il debug
 * Se la macro DEBUG è definita utilizzo MASK per stampare a video i messaggi di tracing.
 * Se MASK = 1 stampa i messaggi D1
 * Se MASK = 2 stampa i messaggi D2
 * se MASK = 3 stampa i messaggi D1 e D2
 */
unsigned int MASK = 1;

#endif


ALLEGRO_BITMAP *giocatore[13];/**< Array che contiene gli oggetti di tipo ::Bolle*/
ALLEGRO_BITMAP *nemici[4]; /**< Array che contiene gli oggetti di tipo ::Robot*/
ALLEGRO_BITMAP *bonus[6]; /**< Array che contiene gli oggetti di tipo ::Frutta*/

/** Variabile per la memorizzazione dell'ultima mossa fatta (movimento a destra o sinistra)
 * Serve per disegnare la posizione del drago a destra o seinistra mentre spara le bolle, in base
 * a quale era la sua posizione precende (mentre si muoveva).
 */
int prevDir = RIGHT;
/** Variabile per memorizzare se ci troviamo nella ::FASE_GIOCO o ::FASE_PAUSA.
 * Serve per intercambiare gli stati Pausa e Gioco in modo da poter tornare alla fase gioco dalla fase pausa,
 * e viceversa. 
 */
int prevStato = FASE_GIOCO;

/** Oggetto di tipo ::Drago
 * E' l'oggetto che usa il giocatore per interagire con il gioco.
 * Può sparare delle bolle, oppure spostarsi a destra o a sinistra, tramite le apposite funzioni.
 */

/**Array collegato all'enumeratore ::KEYS*/
bool tasti[4] = {false, false, false, false};


ALLEGRO_SAMPLE *spara = NULL; /**<Musica ripodotta durante lo sparo  della bolle*/
ALLEGRO_SAMPLE *perso = NULL; /**<Musica riprodotta una volta sola durante la ::FASE_PERSO*/
ALLEGRO_SAMPLE *titolo = NULL; /**<Musica riprodotta in loop durante la ::FASE_TITOLO*/
ALLEGRO_SAMPLE *bobblefruit = NULL; /**<Musica riprodotta in loop durante la ::FASE_GIOCO*/
ALLEGRO_SAMPLE_INSTANCE *canzoneGioco = NULL; /**<E' una "Playable Instance". Fa riferimento a ::bobblefruit e mantiene le informazioni per il loop*/
ALLEGRO_SAMPLE_INSTANCE *canzoneTitolo = NULL; /**<E' una "Playable Instance". Fa riferimento a ::titolo e mantiene le informazioni per il loop*/

 /** Oggetto di tipo ::Drago
 * E' l'oggetto che usa il giocatore per interagire con il gioco.
 * Può sparare delle bolle, oppure spostarsi a destra o a sinistra, tramite le apposite funzioni.
 */
Drago drago;

/** Oggetto di tipo ::Bolle
 * E' un array di elemento ::Bolle che sono le armi del ::drago, per uccidere i ::robot .
 * Può inoltre uccidere la frutta/dolci ma è sconveniente per fa perdere punti.
 */
Bolle bolle[NUM_BOLLE];

/** Oggetto di tipo ::Frutta
 * E' un array di elemento ::Frutta che sono i bonus del ::drago .
 * Sono i bonus del drago se presi e non lasciati cadere o uccisi. Se sono lasciati cadere
 * non succede niente, se uccisi si perdono punti. Onde evitare che il giocatore spari
 * bolle a raffica. Inoltre portano a un punteggio negativo che uccide il drago.
 */
Frutta frutta[NUM_FRUTTA];

/** Oggetto di tipo ::Robot
 * E' un array di elemento ::Robot, sono i nemici del giocatore che deve uccidere, per guadagnare
 * punti. Se persi oppure se toccano il drago, quest'ultimo perderà una vita.
 */
Robot robot[NUM_ROBOTS];

/**Funzione che ci permette di spostarci tra gli stati del gioco. 
 * Questa funzione permette di passare attraverso le fasi di gioco 
 * come è specificato nella descrizione dell'enum ::STATO
 */
void cambia_stato(int &stato, int nuovoStato);

int main(int argc, char *argv[])
{
	bool chiudi_finestra= false; /* Variabile per la gestione della chiusura della finestra di gioco*/
	bool ridisegna = true; /* Variabile che ci indica se è necessario ridisegnare o meno gli oggetti*/
	const int FPS = 50; /*Numero di Frame per Secondo.*/

	int stato = FASE_TITOLO; /* Variabile per la gestione dell'alternarsi della pausa e del gioco*/

	/*
	 *	Sfondi usati nel gioco, sono oggetti di tipo ::Sfondo.
	 */
	Sfondo ST;
	Sfondo SD;
	Sfondo T1;
	Sfondo T2;
	Sfondo STitolo;
	Sfondo SPerso;

	
	/*
	 * Variabili di Allegro
	 */
	ALLEGRO_DISPLAY *display = NULL; /* Rappresenta il display o finestra di gioco*/
	ALLEGRO_EVENT_QUEUE *coda_eventi= NULL; /* Coda per la gestione degli eventi*/
	ALLEGRO_TIMER *timer = NULL; /* Tipo di dato astratto che rappresenta un oggetto di tipo timer */
	
	/*
	 * Font utilizzati nel programma
	 */
	ALLEGRO_FONT *font2 = NULL; 
	ALLEGRO_FONT *font17 = NULL;
	ALLEGRO_FONT *font18 = NULL;
	ALLEGRO_FONT *font4 = NULL;
	
	/*
	 * Sfondi utilizzati nel programma.
	 */
	ALLEGRO_BITMAP *sfondo1 = NULL;
	ALLEGRO_BITMAP *sfondo2 = NULL;
	ALLEGRO_BITMAP *titolo1 = NULL;
	ALLEGRO_BITMAP *sfondotitolo = NULL;
	ALLEGRO_BITMAP *sfondoperso = NULL;
	ALLEGRO_BITMAP *titolo2 = NULL;

	ALLEGRO_BITMAP *cuore = NULL;/* usato per indicare il numero delle vite*/


	
	/*
	 *	Inizializzazione di allegro. Se fallisce restituisce -1.
	 */
	if(!al_init())
		return -1;
	
	display = al_create_display(WIDTH, HEIGHT);	

	if(!display)
		return -1;
	

	/*Funzione inclusa in #include <allegro5/allegro_primitives.h>
	 * Utilizzata per il disegno delle forme geometriche comuni
	 * In questo programma la utilizzo per disegnare le ::Bolle
	 */
	if(!al_init_primitives_addon())
		return -1;
	
	/*Installa i driver per la tastiera.
	 * Ritorna vero se ha avuto successo, se il driver è già connesso non succede niente e ritorna vero.
	 */
	if(!al_install_keyboard())
		return -1;
	
	/*Permette l'utilizzo dei font*/
	al_init_font_addon();
	/*Utilizzato per riconoscere i font caricati .ttf*/
	al_init_ttf_addon();
	/*Supporta il caricamento di immagini di varie estensioni tra cui .png*/
	al_init_image_addon();
	
	/*Installa l'audio subsystem. Ritorna vero se ha avuto successo*/
	al_install_audio();
	al_init_acodec_addon();

	/*Caricamento delle immagini.png dalla dierctory.
	 *Carica le immagini del drago in un array di dimensione uguale al numero di immagini.
	*/
	for(int i= 0; i < 13; i++)
	{
		stringstream str;
		str<<i+1<<".png";
		/**
		 *Una string stream è una classe del C++ che ti permette di usare una 
		 * stringa come risorsa e destinazione di dati per uno stream
		 */
		giocatore[i]= al_load_bitmap(str.str().c_str());
	}

	/*Caricamento delle immagini dei robot in un array di dimensioni uguali al numero di immagini*/
	nemici[0]= al_load_bitmap("e1.png");
	nemici[1]= al_load_bitmap("e2.png");
	nemici[2]= al_load_bitmap("e3.png");
	nemici[3]= al_load_bitmap("e4.png");
	
	/*Caricamento delle immagini deilla frutta in un array di dimensioni uguali al numero di immagini*/
	bonus[0]= al_load_bitmap("t1.png");
	bonus[1]= al_load_bitmap("t2.png");
	bonus[2]= al_load_bitmap("t3.png");
	bonus[3]= al_load_bitmap("t4.png");
	bonus[4]= al_load_bitmap("t5.png");
	bonus[5]= al_load_bitmap("t6.png");
	
	/*Acquisizione delle immagini da usare come sfondo*/
	sfondo1 = al_load_bitmap("sfondo1.png");
	sfondo2 = al_load_bitmap("sfondo2.png");
	titolo1 = al_load_bitmap("bobble.png");
	titolo2 = al_load_bitmap("fruit.png");
	sfondotitolo = al_load_bitmap("sfondotitolo.png");
	sfondoperso = al_load_bitmap("sfondoperso.png");
	cuore = al_load_bitmap("cuore.png");
	
	/* Riserva un numero di "sample istance" collegandole al mixer di default.
	 * Se non esiste un mixer di default quando la funzione è chimata viene creato automaticamente.
	 */
	al_reserve_samples(10);

	/*Acquisizione dei file audio dalla directory in cui si trovano i file*/
	titolo = al_load_sample("titolo.ogg");
	spara = al_load_sample("spara.ogg");
	perso = al_load_sample("perso.ogg");
	bobblefruit = al_load_sample("gioco.ogg");

	/* Crea un flusso utilizzando i dati forniti.
	 * Deve essere legato a un mixer prima di essere riprodotto.
	 */
	canzoneGioco = al_create_sample_instance(bobblefruit);
	canzoneTitolo = al_create_sample_instance(titolo);
	
	/* Imposta la modalità di riproduzione
	 * @return truse se ha avuto successo
	 */
	al_set_sample_instance_playmode(canzoneGioco, ALLEGRO_PLAYMODE_LOOP);
	al_set_sample_instance_playmode(canzoneTitolo, ALLEGRO_PLAYMODE_LOOP);

	/*
	 * Lega l'istanza al mixer, che prima non deve essere legata a nienet.
	 */
	al_attach_sample_instance_to_mixer(canzoneGioco, al_get_default_mixer());
	al_attach_sample_instance_to_mixer(canzoneTitolo, al_get_default_mixer());

	/*
	 * Crea una coda vuota di esempi
	 * @return il puntatore all'oggetto se ha avuto successo
	 * @return NULL se non ha avuto successo.
	 */
	if(!(coda_eventi= al_create_event_queue()))
		D1(cout<<"Coda eventi non creata"<<endl);;
	
	/*
	 * Installa un nuovo timer
	 * 1.0 / FPS è in secondo per tick. Deve essere positivo.
	 * Il timer inizialmente è fermo.
	 * @return puntatore al nuovo oggetto se ha avuto successo
	 * @return NULL altrimenti.
	 */
	if(!(timer = al_create_timer(1.0 / FPS)))
		D1(cout<<"Timer non creato"<<endl);;

	/* Funzione utilizzata per generare semi diversi per ogni chiamata del rand().*/
	srand(time(NULL));
	
	/*
	 * Chiamata alle funzioni di inizializzazione degli oggetti ::Drago, ::Bolle, ::Robot, ::Frutta.
	 */
	crea_drago(drago);
	crea_bolle(bolle, NUM_BOLLE);
	crea_robot(robot, NUM_ROBOTS);
	crea_frutta(frutta, NUM_FRUTTA);
	
	/* Chiamata alle funzione di inizializzazione degli sfondi*/
	crea_sfondo(SD, 0, 0, 1, 0, 800, 700, -1, 1, sfondo1);
	crea_sfondo(ST, 0, 0, 0, 2, 500, 1400, 1, -1, sfondo2);
	crea_sfondo(T1, 0, 0, 0, 0, 500, 700, 1, 1, titolo1);
	crea_sfondo(T2, 0, 0, 0, 0, 500, 700, 1, 1, titolo2);
	crea_sfondo(STitolo, 0, 0, 1, 0, 800, 700, -1, 1, sfondotitolo);
	crea_sfondo(SPerso, 0, 0, 1, 0, 800, 700, -1, 1, sfondoperso);
	
	/* Caricamento dei font .ttf presenti nella directory corrente*/
	font17 = al_load_font("ciccio.ttf", 80, 0);
	font18 = al_load_font("orbitron_black.ttf", 18, 0);
	font2 = al_load_font("orbitron_black.ttf", 17, 0);
	font4 = al_load_font("Explosive.ttf", 57, 0);	

	/*
	 * Indico gli eventi che devono essere registrati nella coda di eventi
	 * preventivamente creata.
	 */
	al_register_event_source(coda_eventi, al_get_keyboard_event_source());
	al_register_event_source(coda_eventi, al_get_timer_event_source(timer));
	al_register_event_source(coda_eventi, al_get_display_event_source(display));

	al_start_timer(timer);/**<Faccio partire il timer*/
	
	while(!chiudi_finestra)
	{
		D2(cout<<"Chiudi finestra = "<<chiudi_finestra<<endl);
		ALLEGRO_EVENT evento;
		al_wait_for_event(coda_eventi, &evento);

		/*
		 * Entro in questo if se l'evento è di tipo EVENT_TIMER
		 */
		if(evento.type == ALLEGRO_EVENT_TIMER)
		{
			ridisegna = true;
			/* Controllo quali tasti sono stati premuti*/
			if(tasti[LEFT])
				muovi_drago_sx(drago);/**<muovi_drago_sx Muovo il drago a sinistra se è stato premuto la freccia sinistra.*/
			else if(tasti[RIGHT])
				muovi_drago_dx(drago);/**<muovi_drago_dx Muovo il drago a destra se è stato premuto la freccia destra.*/
			
			/* Nel caso in cui mi trovo nella ::FASE_TITOLO aggiorno gli sfondi e riproduco l'audio ::canzoneTitolo*/
			if(stato == FASE_TITOLO)
			{
				al_play_sample_instance(canzoneTitolo);
				update_sfondo(STitolo);
			}
			
			/*Nel caso in cui mi trovo nella ::FASE_GIOCO aggiorno gli sfondi e riproduco l'audio ::canzoneTitolo
			 * Gestisco le collisioni possibili e inizializzo la partenza di nuovi robot e frutta.
			 * Controllo che le collisioni non abbiano ucciso il ::drago .
			 */			
			else if(stato == FASE_GIOCO)
			{
				update_sfondo(ST);
				update_sfondo(SD);

				update_bolle(bolle, NUM_BOLLE);
				inizializza_partenza_robot(robot, NUM_ROBOTS);
				inizializza_partenza_frutta(frutta, NUM_FRUTTA);
				update_robot(robot, NUM_ROBOTS);
				update_frutta(frutta, NUM_FRUTTA);
				gestisci_collisione_bolle(bolle, NUM_BOLLE, robot, NUM_ROBOTS, frutta, NUM_FRUTTA, drago);
				gestisci_collisioni_robot(robot, NUM_ROBOTS, drago);
				gestisci_collisioni_frutta(frutta, NUM_FRUTTA, drago);
			
				if(drago.vite <= 0)
					cambia_stato(stato, FASE_PERSO);
			}
			else if(stato == FASE_PAUSA)
			{
			}
			else if(stato == FASE_PERSO)
			{
				update_sfondo(SPerso);
			}
		}
		/*Chiudo la finestra di gioco se è stata chiusa*/
		else if(evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			chiudi_finestra= true;
		}
		/*
		 * Gestisco per ogni tatso l'azione corrispondente, anche in funzione a quale fase di gioco mi trovo.
		 */
		else if(evento.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch(evento.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				chiudi_finestra= true;
				break;
			case ALLEGRO_KEY_LEFT:
				if(stato != FASE_PAUSA)
				{
					tasti[LEFT] = true;
					drago.frameAttuale = 5;
					drago.maxFrame = 9;
					prevDir = LEFT;
				}
				break;
			case ALLEGRO_KEY_RIGHT:
				if(stato != FASE_PAUSA)
				{
					tasti[RIGHT] = true;
					drago.frameAttuale = 0;
					drago.maxFrame = 4;
					prevDir = RIGHT;
				}
				break;
			case ALLEGRO_KEY_SPACE:
				tasti[SPACE] = true;
				if(prevDir == RIGHT)
				{
					drago.frameAttuale = 10;
					drago.maxFrame = 10;
				}
				else
				{
					drago.frameAttuale = 12;
					drago.maxFrame = 12;
				}
				if(stato == FASE_TITOLO)
					cambia_stato(stato, FASE_GIOCO);
				else if(stato == FASE_GIOCO)
					spara_bolle(bolle, NUM_BOLLE, drago);
				else if(stato == FASE_PERSO)
					cambia_stato(stato, FASE_TITOLO);
				break;
			case ALLEGRO_KEY_P:
				tasti[P] = true;
				if(stato == FASE_GIOCO)
				{
					prevStato = FASE_GIOCO;
					cambia_stato(stato, FASE_PAUSA);
				}
				else if(stato == FASE_PAUSA)
				{
					prevStato = FASE_PAUSA;
					cambia_stato(stato, FASE_GIOCO);
				}
			}	
			
		}
		else if(evento.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch(evento.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				chiudi_finestra= true;
				break;
			case ALLEGRO_KEY_LEFT:
				tasti[LEFT] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				tasti[RIGHT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				tasti[SPACE] = false;
			case ALLEGRO_KEY_P:
				tasti[P] = false;
				break;
			}
		}
		
		/*
		 * if(!tasti[LEFT] && !tasti[RIGHT] && !tasti[SPACE]) Utilizzo questo if per impostare l'immagine del drago nella posizione da fermo 
		 * senza indurre a nessun movimento.
		 */
		if(!tasti[LEFT] && !tasti[RIGHT] && !tasti[SPACE])
		{
			drago.frameAttuale = 11;
			drago.maxFrame = 11;
		}
		
		/*
		 * E' importante che prima di ridisegnare la nostra coda degli eventi sia vuota
		 * Altrimenti potrebbero crearsi dei disagi durante il ciclo di aggiornamento.
		 * RIdisegnamo la schermata in base alla fase di gioco in cui ci troviamo.
		 */
		if(ridisegna && al_is_event_queue_empty(coda_eventi))
		{
			ridisegna = false; 
			
			if(stato == FASE_TITOLO)
			{
				disegna_sfondo(STitolo);
				disegna_sfondo(T1);
				disegna_sfondo(T2);
				al_draw_textf(font18, al_map_rgb(120, 200, 0), 20, 380, 0, "PREMI LA BARRA SPAZIATRICE PER PARTIRE");
				al_draw_textf(font2,  al_map_rgb(255, 0, 255), 20, 410, 0, "ISTRUZIONI:");
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 440, 0, "BARRA SPAZIATRICE PER SPARARE");
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 460, 0, "FRECCE DESTRA E SINISTRA PER MUOVERSI");
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 480, 0, "100 pt. per ogni robot ucciso");
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 500, 0, "100 pt per ogni cibo mangiato");
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 520, 0, "-100 pt per ogni cibo ucciso");
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 540, 0, "-1 vita per ogni robot perso");
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 560, 0, "Se arrivi a un pt negativo perdi");
				
				al_draw_textf(font18, al_map_rgb(250, 200, 255), 20, 600, 0, "PREMI P PER METTERE IN PAUSA");
			}
			else if(stato == FASE_GIOCO)
			{
				disegna_sfondo(ST);
				disegna_sfondo(SD);
				disegna_drago(drago);
				disegna_robot(robot, NUM_ROBOTS);
				disegna_frutta(frutta, NUM_FRUTTA);
				disegna_bolle(bolle, NUM_BOLLE);
				
				for(int i=0; i<drago.vite; i++)
					al_draw_bitmap(cuore, i*30 + 10, 25, 0);
				
				al_draw_textf(font18, al_map_rgb(255, 0, 255), 10, 5, 0, "Vite");
				al_draw_textf(font18, al_map_rgb(255, 0, 255), 300, 5, 0, "Punteggio");
				al_draw_textf(font2, al_map_rgb(255, 0, 0), 300, 20, 0, "%d", drago.punti);
			}
			else if(stato == FASE_PAUSA)
			{
				disegna_sfondo(ST);
				disegna_sfondo(SD);
				disegna_drago(drago);
				disegna_robot(robot, NUM_ROBOTS);
				disegna_frutta(frutta, NUM_FRUTTA);
				disegna_bolle(bolle, NUM_BOLLE);
				
				for(int i=0; i<drago.vite; i++)
					al_draw_bitmap(cuore, i*30 + 10, 25, 0);
				
				al_draw_textf(font18, al_map_rgb(255, 0, 255), 10, 5, 0, "Vite");
				al_draw_textf(font18, al_map_rgb(255, 0, 255), 300, 5, 0, "Punteggio");
				al_draw_textf(font2, al_map_rgb(255, 0, 0), 300, 20, 0, "%d", drago.punti);
			
				al_draw_textf(font17, al_map_rgb(0, 255, 0), WIDTH/2, HEIGHT/2, ALLEGRO_ALIGN_CENTRE, "PAUSA");
			}
			else if(stato == FASE_PERSO)
			{
				disegna_sfondo(SPerso);
				al_draw_textf(font4, al_map_rgb(153, 102, 204), WIDTH/2, HEIGHT/2 - 100, ALLEGRO_ALIGN_CENTRE, "Hai");
				al_draw_textf(font4, al_map_rgb(153, 102, 204), WIDTH/2, HEIGHT/2 - 50, ALLEGRO_ALIGN_CENTRE, "totalizzato");
				al_draw_textf(font4, al_map_rgb(246, 172, 0), WIDTH/2, HEIGHT/2 + 10, ALLEGRO_ALIGN_CENTRE, "%d", drago.punti);
				al_draw_textf(font4, al_map_rgb(153, 102, 204), WIDTH/2, HEIGHT/2 + 90, ALLEGRO_ALIGN_CENTRE, "punti", drago.punti);
				
				al_draw_textf(font18, al_map_rgb(120, 200, 255), WIDTH/2, HEIGHT/2 + 200, ALLEGRO_ALIGN_CENTRE, "PREMI LA BARRA SPAZIATRICE ");
			}
		
			al_flip_display();
			al_clear_to_color(al_map_rgb(0,0,0));
		}
	}
	 

	for(int i=0; i<13; i++)
		al_destroy_bitmap(giocatore[i]);
	for(int i=0; i<4; i++)
		al_destroy_bitmap(nemici[i]);
	for(int i=0; i<6; i++)
		al_destroy_bitmap(bonus[i]);	
		
	/*
	 * al_destroy_... Distruggiamo tutti gli oggetti creti nel corso del programma, tra cui gli audio e le immagini
	 * onde evitare il memory leak.
	 */	
	al_destroy_sample(spara);
	al_destroy_sample(titolo);
	al_destroy_sample(bobblefruit);
	al_destroy_sample(perso);
	al_destroy_sample_instance(canzoneGioco);
	al_destroy_sample_instance(canzoneTitolo);
	al_destroy_event_queue(coda_eventi);
	al_destroy_timer(timer);
	al_destroy_font(font18);
	al_destroy_font(font17);
	al_destroy_font(font2);
	al_destroy_font(font4);
	al_destroy_display(display);						
	al_destroy_bitmap(sfondo2);
	al_destroy_bitmap(sfondo1);
	al_destroy_bitmap(sfondotitolo);
	al_destroy_bitmap(sfondoperso);
	al_destroy_bitmap(cuore);

	
	return 0;
}

void cambia_stato(int &stato, int nuovoStato)
{
	D1(cout<<"stato = "<<stato<<endl);
	stato = nuovoStato;
	D1(cout<<"stato nuovo = "<<stato<<endl);
	

	if(stato == FASE_TITOLO)
	{
		al_stop_samples(); /** al_stop_samples(); Fermiamo l'audio riprodotto in fasi del gioco terminate*/
		prevStato = FASE_GIOCO;
	}
	else if(stato == FASE_GIOCO)
	{
		if(prevStato == FASE_GIOCO)
		{
			al_stop_sample_instance(canzoneTitolo);
			crea_drago(drago);
			crea_bolle(bolle, NUM_BOLLE);
			crea_robot(robot, NUM_ROBOTS);
			crea_frutta(frutta, NUM_FRUTTA);
			al_play_sample_instance(canzoneGioco);/** al_play_sample_instance(canzoneGioco) Riproduciamo l'audio in ::FASE_GIOCO*/
		}
		else if(prevStato == FASE_PAUSA)
		{
			al_play_sample_instance(canzoneGioco);
		}

	}
	else if(stato == FASE_PAUSA)
	{

	}
	else if(stato == FASE_PERSO)
	{
		al_stop_sample_instance(canzoneGioco);/** al_stop_sample_instance(canzoneGioco) Fermiamo l'audio riprodotto in ::FASE_GIOCO*/
		al_play_sample(perso, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0);/** al_play_sample(perso, 1, 0, 1, ALLEGRO_PLAYMODE_ONCE, 0) Riproduciamo l'audio in ::FASE_PERSO*/
	}
}

